#lang racket/base
(require racket/include)

(include "config.rktl")

(define (f x) x)
(set! f f)

'----------------------------------------

;; Baseline loop performance
'loop
(times
 (let loop ([i N])
   (if (zero? i)
       0
       (loop (sub1 i)))))

;; How much does it const to allocate a pair each time?
;;  See "attach.scm"
'pair-loop
(times
 (let loop ([i N] [p #f])
   (if (zero? i)
       p
       (loop (sub1 i) (cons i i)))))

;; Baseline for continuation-growing non-tail recursion (note `M` instead of `N`)
'nontail
(times
 (let loop ([i M])
   (if (zero? i)
       0
       (add1 (loop (sub1 i))))))

;; How much more does it add to allocate pairs?
'pairs-nontail
(times
 (let loop ([i M] [p #f])
   (if (zero? i)
       (car p)
       (add1 (loop (sub1 i) (cons i (cons i p)))))))

;; Racket CS time is 12% slower than CS time due to
;;  the extra code generated by `#%app`
'indirect-nontail-argument-loop
(times
 (let ([f f])
   (let loop ([i N])
     (if (zero? i)
         0
         (loop (f (sub1 i)))))))
